
/**
 * 校验手机号格式
 * @param {string} phone - 手机号码
 * @returns {boolean} 是否为有效的手机号
 * @example
 * validPhone('13812345678') // true
 * validPhone('1381234567') // false
 */
export const validPhone = (phone) => {
  if (!phone || typeof phone !== 'string') return false
  // 中国大陆手机号正则：1开头，第二位为3-9，总共11位数字
  const phoneRegex = /^1[3-9]\d{9}$/
  return phoneRegex.test(phone)
}

/**
 * 校验邮箱格式
 * @param {string} email - 邮箱地址
 * @returns {boolean} 是否为有效的邮箱格式
 * @example
 * validEmail('user@example.com') // true
 * validEmail('invalid-email') // false
 */
export const validEmail = (email) => {
  if (!email || typeof email !== 'string') return false
  // 邮箱正则表达式
  const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
  return emailRegex.test(email)
}

/**
 * 校验身份证号格式
 * @param {string} idCard - 身份证号码
 * @returns {boolean} 是否为有效的身份证号
 * @example
 * validIdCard('110101199003077777') // true
 * validIdCard('12345678901234567') // false
 */
export const validIdCard = (idCard) => {
  if (!idCard || typeof idCard !== 'string') return false

  // 18位身份证号正则
  const idCardRegex = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/

  if (!idCardRegex.test(idCard)) return false

  // 校验码验证
  const weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
  const checkCodes = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']

  let sum = 0
  for (let i = 0; i < 17; i++) {
    sum += parseInt(idCard[i]) * weights[i]
  }

  const checkCode = checkCodes[sum % 11]
  return checkCode === idCard[17].toUpperCase()
}

/**
 * 校验密码强度
 * @param {string} password - 密码
 * @param {Object} options - 校验选项
 * @param {number} options.minLength - 最小长度，默认8
 * @param {number} options.maxLength - 最大长度，默认20
 * @param {boolean} options.requireUppercase - 是否需要大写字母，默认true
 * @param {boolean} options.requireLowercase - 是否需要小写字母，默认true
 * @param {boolean} options.requireNumbers - 是否需要数字，默认true
 * @param {boolean} options.requireSpecialChars - 是否需要特殊字符，默认true
 * @returns {Object} 校验结果对象
 * @example
 * validPassword('Abc123!@#') // { valid: true, strength: 'strong', message: '密码强度：强' }
 * validPassword('123456') // { valid: false, strength: 'weak', message: '密码过于简单' }
 */
export const validPassword = (password, options = {}) => {
  const defaultOptions = {
    minLength: 8,
    maxLength: 20,
    requireUppercase: true,
    requireLowercase: true,
    requireNumbers: true,
    requireSpecialChars: true
  }

  const opts = { ...defaultOptions, ...options }

  if (!password || typeof password !== 'string') {
    return { valid: false, strength: 'invalid', message: '密码不能为空' }
  }

  // 长度检查
  if (password.length < opts.minLength) {
    return { valid: false, strength: 'weak', message: `密码长度不能少于${opts.minLength}位` }
  }

  if (password.length > opts.maxLength) {
    return { valid: false, strength: 'weak', message: `密码长度不能超过${opts.maxLength}位` }
  }

  let score = 0
  const checks = []

  // 检查大写字母
  if (/[A-Z]/.test(password)) {
    score += 1
    checks.push('uppercase')
  } else if (opts.requireUppercase) {
    return { valid: false, strength: 'weak', message: '密码必须包含大写字母' }
  }

  // 检查小写字母
  if (/[a-z]/.test(password)) {
    score += 1
    checks.push('lowercase')
  } else if (opts.requireLowercase) {
    return { valid: false, strength: 'weak', message: '密码必须包含小写字母' }
  }

  // 检查数字
  if (/\d/.test(password)) {
    score += 1
    checks.push('numbers')
  } else if (opts.requireNumbers) {
    return { valid: false, strength: 'weak', message: '密码必须包含数字' }
  }

  // 检查特殊字符
  if (/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(password)) {
    score += 1
    checks.push('special')
  } else if (opts.requireSpecialChars) {
    return { valid: false, strength: 'weak', message: '密码必须包含特殊字符' }
  }

  // 判断强度
  let strength = 'weak'
  let message = '密码强度：弱'

  if (score >= 4) {
    strength = 'strong'
    message = '密码强度：强'
  } else if (score >= 3) {
    strength = 'medium'
    message = '密码强度：中等'
  }

  return { valid: true, strength, message, score, checks }
}

/**
 * 校验用户名格式
 * @param {string} username - 用户名
 * @param {Object} options - 校验选项
 * @param {number} options.minLength - 最小长度，默认3
 * @param {number} options.maxLength - 最大长度，默认20
 * @param {boolean} options.allowChinese - 是否允许中文，默认false
 * @returns {Object} 校验结果对象
 * @example
 * validUsername('user123') // { valid: true, message: '用户名格式正确' }
 * validUsername('u') // { valid: false, message: '用户名长度不能少于3位' }
 */
export const validUsername = (username, options = {}) => {
  const defaultOptions = {
    minLength: 3,
    maxLength: 20,
    allowChinese: false
  }

  const opts = { ...defaultOptions, ...options }

  if (!username || typeof username !== 'string') {
    return { valid: false, message: '用户名不能为空' }
  }

  if (username.length < opts.minLength) {
    return { valid: false, message: `用户名长度不能少于${opts.minLength}位` }
  }

  if (username.length > opts.maxLength) {
    return { valid: false, message: `用户名长度不能超过${opts.maxLength}位` }
  }

  // 用户名规则：字母开头，可包含字母、数字、下划线
  let usernameRegex = /^[a-zA-Z][a-zA-Z0-9_]*$/

  // 如果允许中文，修改正则表达式
  if (opts.allowChinese) {
    usernameRegex = /^[a-zA-Z\u4e00-\u9fa5][a-zA-Z0-9_\u4e00-\u9fa5]*$/
  }

  if (!usernameRegex.test(username)) {
    const message = opts.allowChinese
      ? '用户名必须以字母或中文开头，只能包含字母、数字、下划线和中文'
      : '用户名必须以字母开头，只能包含字母、数字和下划线'
    return { valid: false, message }
  }

  return { valid: true, message: '用户名格式正确' }
}

/**
 * 校验数字格式
 * @param {string|number} value - 要校验的值
 * @param {Object} options - 校验选项
 * @param {boolean} options.allowDecimal - 是否允许小数，默认true
 * @param {boolean} options.allowNegative - 是否允许负数，默认true
 * @param {number} options.min - 最小值
 * @param {number} options.max - 最大值
 * @param {number} options.decimalPlaces - 小数位数限制
 * @returns {Object} 校验结果对象
 * @example
 * validNumber('123.45') // { valid: true, message: '数字格式正确' }
 * validNumber('abc') // { valid: false, message: '不是有效的数字格式' }
 */
export const validNumber = (value, options = {}) => {
  const defaultOptions = {
    allowDecimal: true,
    allowNegative: true
  }

  const opts = { ...defaultOptions, ...options }

  if (value === null || value === undefined || value === '') {
    return { valid: false, message: '数字不能为空' }
  }

  const numStr = String(value).trim()

  // 构建正则表达式
  let regex = '^'

  // 负号
  if (opts.allowNegative) {
    regex += '-?'
  }

  // 整数部分
  regex += '\\d+'

  // 小数部分
  if (opts.allowDecimal) {
    if (opts.decimalPlaces) {
      regex += `(\\.\\d{1,${opts.decimalPlaces}})?`
    } else {
      regex += '(\\.\\d+)?'
    }
  }

  regex += '$'

  const numberRegex = new RegExp(regex)

  if (!numberRegex.test(numStr)) {
    return { valid: false, message: '不是有效的数字格式' }
  }

  const num = parseFloat(numStr)

  if (opts.min !== undefined && num < opts.min) {
    return { valid: false, message: `数字不能小于${opts.min}` }
  }

  if (opts.max !== undefined && num > opts.max) {
    return { valid: false, message: `数字不能大于${opts.max}` }
  }

  return { valid: true, message: '数字格式正确', value: num }
}

/**
 * 校验URL格式
 * @param {string} url - URL地址
 * @param {Object} options - 校验选项
 * @param {boolean} options.requireProtocol - 是否必须包含协议，默认true
 * @param {Array} options.allowedProtocols - 允许的协议列表，默认['http', 'https']
 * @returns {Object} 校验结果对象
 * @example
 * validUrl('https://www.example.com') // { valid: true, message: 'URL格式正确' }
 * validUrl('invalid-url') // { valid: false, message: 'URL格式不正确' }
 */
export const validUrl = (url, options = {}) => {
  const defaultOptions = {
    requireProtocol: true,
    allowedProtocols: ['http', 'https']
  }

  const opts = { ...defaultOptions, ...options }

  if (!url || typeof url !== 'string') {
    return { valid: false, message: 'URL不能为空' }
  }

  try {
    const urlObj = new URL(url)

    if (opts.requireProtocol && !urlObj.protocol) {
      return { valid: false, message: 'URL必须包含协议' }
    }

    if (opts.allowedProtocols && opts.allowedProtocols.length > 0) {
      const protocol = urlObj.protocol.replace(':', '')
      if (!opts.allowedProtocols.includes(protocol)) {
        return { valid: false, message: `URL协议必须是：${opts.allowedProtocols.join('、')}` }
      }
    }

    return { valid: true, message: 'URL格式正确' }
  } catch (error) {
    return { valid: false, message: 'URL格式不正确' }
  }
}

/**
 * 校验IP地址格式
 * @param {string} ip - IP地址
 * @param {string} version - IP版本，'v4' | 'v6' | 'both'，默认'v4'
 * @returns {Object} 校验结果对象
 * @example
 * validIp('192.168.1.1') // { valid: true, message: 'IP地址格式正确', version: 'v4' }
 * validIp('2001:0db8:85a3:0000:0000:8a2e:0370:7334', 'v6') // { valid: true, message: 'IP地址格式正确', version: 'v6' }
 */
export const validIp = (ip, version = 'v4') => {
  if (!ip || typeof ip !== 'string') {
    return { valid: false, message: 'IP地址不能为空' }
  }

  const ipv4Regex = /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
  const ipv6Regex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/

  switch (version) {
    case 'v4':
      if (ipv4Regex.test(ip)) {
        return { valid: true, message: 'IP地址格式正确', version: 'v4' }
      }
      return { valid: false, message: 'IPv4地址格式不正确' }

    case 'v6':
      if (ipv6Regex.test(ip)) {
        return { valid: true, message: 'IP地址格式正确', version: 'v6' }
      }
      return { valid: false, message: 'IPv6地址格式不正确' }

    case 'both':
      if (ipv4Regex.test(ip)) {
        return { valid: true, message: 'IP地址格式正确', version: 'v4' }
      }
      if (ipv6Regex.test(ip)) {
        return { valid: true, message: 'IP地址格式正确', version: 'v6' }
      }
      return { valid: false, message: 'IP地址格式不正确' }

    default:
      return { valid: false, message: '不支持的IP版本' }
  }
}

/**
 * 校验银行卡号格式（使用Luhn算法）
 * @param {string} cardNumber - 银行卡号
 * @returns {Object} 校验结果对象
 * @example
 * validBankCard('6222600260001072444') // { valid: true, message: '银行卡号格式正确' }
 * validBankCard('1234567890123456') // { valid: false, message: '银行卡号校验失败' }
 */
export const validBankCard = (cardNumber) => {
  if (!cardNumber || typeof cardNumber !== 'string') {
    return { valid: false, message: '银行卡号不能为空' }
  }

  // 移除空格和连字符
  const cleanNumber = cardNumber.replace(/[\s-]/g, '')

  // 检查是否全为数字且长度在13-19位之间
  if (!/^\d{13,19}$/.test(cleanNumber)) {
    return { valid: false, message: '银行卡号格式不正确' }
  }

  // Luhn算法校验
  let sum = 0
  let isEven = false

  // 从右到左遍历
  for (let i = cleanNumber.length - 1; i >= 0; i--) {
    let digit = parseInt(cleanNumber[i])

    if (isEven) {
      digit *= 2
      if (digit > 9) {
        digit -= 9
      }
    }

    sum += digit
    isEven = !isEven
  }

  if (sum % 10 === 0) {
    return { valid: true, message: '银行卡号格式正确' }
  } else {
    return { valid: false, message: '银行卡号校验失败' }
  }
}

/**
 * 校验车牌号格式
 * @param {string} plateNumber - 车牌号
 * @param {string} type - 车牌类型，'normal' | 'newEnergy' | 'both'，默认'both'
 * @returns {Object} 校验结果对象
 * @example
 * validPlateNumber('京A12345') // { valid: true, message: '车牌号格式正确', type: 'normal' }
 * validPlateNumber('京AD12345') // { valid: true, message: '车牌号格式正确', type: 'newEnergy' }
 */
export const validPlateNumber = (plateNumber, type = 'both') => {
  if (!plateNumber || typeof plateNumber !== 'string') {
    return { valid: false, message: '车牌号不能为空' }
  }



  // 普通车牌正则：省份简称 + 字母 + 5位数字或字母
  const normalPlateRegex = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼][A-Z][A-HJ-NP-Z0-9]{5}$/

  // 新能源车牌正则：省份简称 + 字母 + 6位数字或字母（第1位或第6位必须是字母）
  const newEnergyPlateRegex = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼][A-Z]([A-HJ-NP-Z][A-HJ-NP-Z0-9]{5}|[A-HJ-NP-Z0-9]{5}[A-HJ-NP-Z])$/

  switch (type) {
    case 'normal':
      if (normalPlateRegex.test(plateNumber)) {
        return { valid: true, message: '车牌号格式正确', type: 'normal' }
      }
      return { valid: false, message: '普通车牌号格式不正确' }

    case 'newEnergy':
      if (newEnergyPlateRegex.test(plateNumber)) {
        return { valid: true, message: '车牌号格式正确', type: 'newEnergy' }
      }
      return { valid: false, message: '新能源车牌号格式不正确' }

    case 'both':
      if (normalPlateRegex.test(plateNumber)) {
        return { valid: true, message: '车牌号格式正确', type: 'normal' }
      }
      if (newEnergyPlateRegex.test(plateNumber)) {
        return { valid: true, message: '车牌号格式正确', type: 'newEnergy' }
      }
      return { valid: false, message: '车牌号格式不正确' }

    default:
      return { valid: false, message: '不支持的车牌类型' }
  }
}

/**
 * 校验统一社会信用代码
 * @param {string} creditCode - 统一社会信用代码
 * @returns {Object} 校验结果对象
 * @example
 * validCreditCode('91110000000000000A') // { valid: true, message: '统一社会信用代码格式正确' }
 */
export const validCreditCode = (creditCode) => {
  if (!creditCode || typeof creditCode !== 'string') {
    return { valid: false, message: '统一社会信用代码不能为空' }
  }

  // 统一社会信用代码为18位，由数字和大写字母组成
  if (!/^[0-9A-HJ-NPQRTUWXY]{2}\d{6}[0-9A-HJ-NPQRTUWXY]{10}$/.test(creditCode)) {
    return { valid: false, message: '统一社会信用代码格式不正确' }
  }

  // 校验码计算
  const weights = [1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28]
  const codes = '0123456789ABCDEFGHJKLMNPQRTUWXY'

  let sum = 0
  for (let i = 0; i < 17; i++) {
    const char = creditCode[i]
    const index = codes.indexOf(char)
    if (index === -1) {
      return { valid: false, message: '统一社会信用代码包含无效字符' }
    }
    sum += index * weights[i]
  }

  const checkCode = codes[31 - (sum % 31)]

  if (checkCode === creditCode[17]) {
    return { valid: true, message: '统一社会信用代码格式正确' }
  } else {
    return { valid: false, message: '统一社会信用代码校验失败' }
  }
}

/**
 * 校验中文姓名格式
 * @param {string} name - 中文姓名
 * @param {Object} options - 校验选项
 * @param {number} options.minLength - 最小长度，默认2
 * @param {number} options.maxLength - 最大长度，默认10
 * @returns {Object} 校验结果对象
 * @example
 * validChineseName('张三') // { valid: true, message: '中文姓名格式正确' }
 * validChineseName('John') // { valid: false, message: '姓名必须为中文' }
 */
export const validChineseName = (name, options = {}) => {
  const defaultOptions = {
    minLength: 2,
    maxLength: 10
  }

  const opts = { ...defaultOptions, ...options }

  if (!name || typeof name !== 'string') {
    return { valid: false, message: '姓名不能为空' }
  }

  if (name.length < opts.minLength) {
    return { valid: false, message: `姓名长度不能少于${opts.minLength}位` }
  }

  if (name.length > opts.maxLength) {
    return { valid: false, message: `姓名长度不能超过${opts.maxLength}位` }
  }

  // 中文姓名正则：只允许中文字符，不允许数字、英文、特殊符号
  const chineseNameRegex = /^[\u4e00-\u9fa5]+$/

  if (!chineseNameRegex.test(name)) {
    return { valid: false, message: '姓名必须为中文' }
  }

  return { valid: true, message: '中文姓名格式正确' }
}

/**
 * 校验日期格式
 * @param {string} dateStr - 日期字符串
 * @param {string} format - 日期格式，默认'YYYY-MM-DD'
 * @param {Object} options - 校验选项
 * @param {string} options.minDate - 最小日期
 * @param {string} options.maxDate - 最大日期
 * @returns {Object} 校验结果对象
 * @example
 * validDate('2024-01-15') // { valid: true, message: '日期格式正确' }
 * validDate('2024/01/15', 'YYYY/MM/DD') // { valid: true, message: '日期格式正确' }
 */
export const validDate = (dateStr, format = 'YYYY-MM-DD', options = {}) => {
  if (!dateStr || typeof dateStr !== 'string') {
    return { valid: false, message: '日期不能为空' }
  }

  // 根据格式构建正则表达式
  let regex = format
    .replace(/YYYY/g, '\\d{4}')
    .replace(/MM/g, '(0[1-9]|1[0-2])')
    .replace(/DD/g, '(0[1-9]|[12]\\d|3[01])')
    .replace(/HH/g, '([01]\\d|2[0-3])')
    .replace(/mm/g, '[0-5]\\d')
    .replace(/ss/g, '[0-5]\\d')

  regex = `^${regex}$`

  if (!new RegExp(regex).test(dateStr)) {
    return { valid: false, message: `日期格式不正确，应为${format}格式` }
  }

  // 尝试创建Date对象验证日期有效性
  let date
  try {
    // 将格式转换为标准格式进行验证
    let standardDateStr = dateStr
    if (format === 'YYYY/MM/DD') {
      standardDateStr = dateStr.replace(/\//g, '-')
    } else if (format === 'DD/MM/YYYY') {
      const parts = dateStr.split('/')
      standardDateStr = `${parts[2]}-${parts[1]}-${parts[0]}`
    } else if (format === 'MM/DD/YYYY') {
      const parts = dateStr.split('/')
      standardDateStr = `${parts[2]}-${parts[0]}-${parts[1]}`
    }

    date = new Date(standardDateStr)

    if (isNaN(date.getTime())) {
      return { valid: false, message: '无效的日期' }
    }

    // 验证日期是否与输入匹配（防止自动修正，如2月30日变成3月2日）
    const year = date.getFullYear()
    const month = date.getMonth() + 1
    const day = date.getDate()

    if (format === 'YYYY-MM-DD' || format === 'YYYY/MM/DD') {
      const expectedStr = format === 'YYYY-MM-DD'
        ? `${year}-${month.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}`
        : `${year}/${month.toString().padStart(2, '0')}/${day.toString().padStart(2, '0')}`

      if (dateStr !== expectedStr) {
        return { valid: false, message: '无效的日期' }
      }
    }

  } catch (error) {
    return { valid: false, message: '无效的日期' }
  }

  // 检查日期范围
  if (options.minDate) {
    const minDate = new Date(options.minDate)
    if (date < minDate) {
      return { valid: false, message: `日期不能早于${options.minDate}` }
    }
  }

  if (options.maxDate) {
    const maxDate = new Date(options.maxDate)
    if (date > maxDate) {
      return { valid: false, message: `日期不能晚于${options.maxDate}` }
    }
  }

  return { valid: true, message: '日期格式正确', date }
}

// ==================== 工具函数和辅助方法 ====================

/**
 * 校验字符串长度
 * @param {string} str - 要校验的字符串
 * @param {Object} options - 校验选项
 * @param {number} options.min - 最小长度
 * @param {number} options.max - 最大长度
 * @param {number} options.exact - 精确长度
 * @returns {Object} 校验结果对象
 * @example
 * validLength('hello', { min: 3, max: 10 }) // { valid: true, message: '长度符合要求' }
 * validLength('hi', { min: 3 }) // { valid: false, message: '长度不能少于3位' }
 */
export const validLength = (str, options = {}) => {
  if (str === null || str === undefined) {
    return { valid: false, message: '内容不能为空' }
  }

  const length = String(str).length

  if (options.exact !== undefined) {
    if (length !== options.exact) {
      return { valid: false, message: `长度必须为${options.exact}位` }
    }
  } else {
    if (options.min !== undefined && length < options.min) {
      return { valid: false, message: `长度不能少于${options.min}位` }
    }

    if (options.max !== undefined && length > options.max) {
      return { valid: false, message: `长度不能超过${options.max}位` }
    }
  }

  return { valid: true, message: '长度符合要求', length }
}

/**
 * 校验数值范围
 * @param {number|string} value - 要校验的数值
 * @param {Object} options - 校验选项
 * @param {number} options.min - 最小值
 * @param {number} options.max - 最大值
 * @param {boolean} options.includeMin - 是否包含最小值，默认true
 * @param {boolean} options.includeMax - 是否包含最大值，默认true
 * @returns {Object} 校验结果对象
 * @example
 * validRange(50, { min: 0, max: 100 }) // { valid: true, message: '数值在有效范围内' }
 * validRange(150, { min: 0, max: 100 }) // { valid: false, message: '数值不能大于100' }
 */
export const validRange = (value, options = {}) => {
  if (value === null || value === undefined || value === '') {
    return { valid: false, message: '数值不能为空' }
  }

  const num = parseFloat(value)
  if (isNaN(num)) {
    return { valid: false, message: '不是有效的数值' }
  }

  const { min, max, includeMin = true, includeMax = true } = options

  if (min !== undefined) {
    if (includeMin ? num < min : num <= min) {
      const operator = includeMin ? '不能小于' : '必须大于'
      return { valid: false, message: `数值${operator}${min}` }
    }
  }

  if (max !== undefined) {
    if (includeMax ? num > max : num >= max) {
      const operator = includeMax ? '不能大于' : '必须小于'
      return { valid: false, message: `数值${operator}${max}` }
    }
  }

  return { valid: true, message: '数值在有效范围内', value: num }
}

/**
 * 使用正则表达式校验
 * @param {string} value - 要校验的值
 * @param {RegExp|string} pattern - 正则表达式或正则字符串
 * @param {string} message - 自定义错误消息
 * @returns {Object} 校验结果对象
 * @example
 * validRegex('abc123', /^[a-z]+\d+$/) // { valid: true, message: '格式正确' }
 * validRegex('ABC123', /^[a-z]+\d+$/, '必须是小写字母加数字') // { valid: false, message: '必须是小写字母加数字' }
 */
export const validRegex = (value, pattern, message = '格式不正确') => {
  if (value === null || value === undefined || value === '') {
    return { valid: false, message: '内容不能为空' }
  }

  let regex
  if (pattern instanceof RegExp) {
    regex = pattern
  } else if (typeof pattern === 'string') {
    try {
      regex = new RegExp(pattern)
    } catch (error) {
      return { valid: false, message: '正则表达式格式错误' }
    }
  } else {
    return { valid: false, message: '无效的正则表达式' }
  }

  if (regex.test(String(value))) {
    return { valid: true, message: '格式正确' }
  } else {
    return { valid: false, message }
  }
}

/**
 * 组合多个校验规则
 * @param {any} value - 要校验的值
 * @param {Array} rules - 校验规则数组
 * @param {string} mode - 校验模式，'all'(所有规则都通过) | 'any'(任一规则通过)，默认'all'
 * @returns {Object} 校验结果对象
 * @example
 * const rules = [
 *   { validator: validLength, options: { min: 6, max: 20 } },
 *   { validator: validRegex, options: [/^[a-zA-Z0-9]+$/, '只能包含字母和数字'] }
 * ]
 * validCombine('abc123', rules) // { valid: true, message: '所有校验规则通过' }
 */
export const validCombine = (value, rules = [], mode = 'all') => {
  if (!Array.isArray(rules) || rules.length === 0) {
    return { valid: true, message: '无校验规则' }
  }

  const results = []

  for (const rule of rules) {
    if (!rule.validator || typeof rule.validator !== 'function') {
      continue
    }

    let result
    if (Array.isArray(rule.options)) {
      result = rule.validator(value, ...rule.options)
    } else if (rule.options) {
      result = rule.validator(value, rule.options)
    } else {
      result = rule.validator(value)
    }

    results.push(result)

    if (mode === 'all' && !result.valid) {
      return result
    }

    if (mode === 'any' && result.valid) {
      return result
    }
  }

  if (mode === 'all') {
    return { valid: true, message: '所有校验规则通过', results }
  } else {
    return { valid: false, message: '所有校验规则都未通过', results }
  }
}

/**
 * 校验是否为空值
 * @param {any} value - 要校验的值
 * @param {Object} options - 校验选项
 * @param {boolean} options.allowZero - 是否允许数字0，默认true
 * @param {boolean} options.allowEmptyString - 是否允许空字符串，默认false
 * @param {boolean} options.allowWhitespace - 是否允许纯空格字符串，默认false
 * @returns {Object} 校验结果对象
 * @example
 * validRequired('hello') // { valid: true, message: '内容不为空' }
 * validRequired('') // { valid: false, message: '内容不能为空' }
 * validRequired(0, { allowZero: false }) // { valid: false, message: '内容不能为空' }
 */
export const validRequired = (value, options = {}) => {
  const { allowZero = true, allowEmptyString = false, allowWhitespace = false } = options

  // null 和 undefined 始终视为空
  if (value === null || value === undefined) {
    return { valid: false, message: '内容不能为空' }
  }

  // 数字0的处理
  if (value === 0 && !allowZero) {
    return { valid: false, message: '内容不能为空' }
  }

  // 字符串的处理
  if (typeof value === 'string') {
    if (value === '' && !allowEmptyString) {
      return { valid: false, message: '内容不能为空' }
    }

    if (value.trim() === '' && !allowWhitespace) {
      return { valid: false, message: '内容不能为空' }
    }
  }

  // 数组的处理
  if (Array.isArray(value) && value.length === 0) {
    return { valid: false, message: '内容不能为空' }
  }

  // 对象的处理
  if (typeof value === 'object' && Object.keys(value).length === 0) {
    return { valid: false, message: '内容不能为空' }
  }

  return { valid: true, message: '内容不为空' }
}

/**
 * 校验两个值是否相等（常用于密码确认）
 * @param {any} value1 - 第一个值
 * @param {any} value2 - 第二个值
 * @param {string} message - 自定义错误消息
 * @returns {Object} 校验结果对象
 * @example
 * validEqual('password123', 'password123') // { valid: true, message: '两次输入一致' }
 * validEqual('password123', 'password456', '两次密码输入不一致') // { valid: false, message: '两次密码输入不一致' }
 */
export const validEqual = (value1, value2, message = '两次输入不一致') => {
  if (value1 === value2) {
    return { valid: true, message: '两次输入一致' }
  } else {
    return { valid: false, message }
  }
}

// ==================== 常用校验规则预设 ====================

/**
 * 常用校验规则预设
 */
export const validRules = {
  // 手机号规则
  phone: {
    validator: validPhone,
    message: '请输入正确的手机号码'
  },

  // 邮箱规则
  email: {
    validator: validEmail,
    message: '请输入正确的邮箱地址'
  },

  // 身份证规则
  idCard: {
    validator: validIdCard,
    message: '请输入正确的身份证号码'
  },

  // 强密码规则
  strongPassword: {
    validator: validPassword,
    options: { minLength: 8, maxLength: 20 },
    message: '密码必须包含大小写字母、数字和特殊字符，长度8-20位'
  },

  // 用户名规则
  username: {
    validator: validUsername,
    options: { minLength: 3, maxLength: 20 },
    message: '用户名必须以字母开头，长度3-20位，只能包含字母、数字和下划线'
  },

  // 中文姓名规则
  chineseName: {
    validator: validChineseName,
    options: { minLength: 2, maxLength: 10 },
    message: '请输入正确的中文姓名'
  }
}

// ==================== 默认导出 ====================

/**
 * 默认导出所有校验函数
 */
export default {
  // 基础校验函数
  validPhone,
  validEmail,
  validIdCard,
  validPassword,
  validUsername,
  validNumber,
  validUrl,
  validIp,

  // 高级校验函数
  validBankCard,
  validPlateNumber,
  validCreditCode,
  validChineseName,
  validDate,

  // 工具函数
  validLength,
  validRange,
  validRegex,
  validCombine,
  validRequired,
  validEqual,

  // 预设规则
  validRules,

  // 版本信息
  version: '1.0.0'
}